package org.sraosha.framework.handler.exception;

import org.sraosha.framework.dto.ApiResult;
import org.sraosha.framework.enumeration.ApiResultEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException;
import org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;
import java.util.stream.Collectors;

@Slf4j
@RestControllerAdvice(annotations = RestController.class)
public class WebExceptionHandler {

    /**
     * 缺少参数异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public ResponseEntity<ApiResult> missingServletRequestParameterExceptionHandler(MissingServletRequestParameterException e) {
        String message = e.getMessage();
        log.error("MissingServletRequestParameterException异常：", e);
        return ApiResultEnum.missingServletRequestParameter(message);
    }

    /**
     * 方法参数验证异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ApiResult> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining("，"));
        log.error("MethodArgumentNotValidException异常：", e);
        return ApiResultEnum.methodArgumentNotValidException(message);
    }

    /**
     * 数据绑定异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(BindException.class)
    public ResponseEntity<ApiResult> bindExceptionHandler(BindException e) {
        ObjectError objectError = e.getBindingResult().getAllErrors().get(0);
        log.error("BindException异常：", e);
        return ApiResultEnum.bindException(objectError.getDefaultMessage());
    }

    /**
     * 单个文件超大异常
     *
     * @param e
     * @return
     * @ExceptionHandler
     */
    @ExceptionHandler(FileSizeLimitExceededException.class)
    public ResponseEntity<ApiResult> fileSizeLimitExceededExceptionHandler(FileSizeLimitExceededException e) {
        String message = e.getMessage();
        log.error("FileSizeLimitExceededException异常：", e);
        return ApiResultEnum.fileSizeLimitExceededException(message);
    }

    /**
     * 请求数据超大异常
     *
     * @param e
     * @return
     * @ExceptionHandler
     */
    @ExceptionHandler(SizeLimitExceededException.class)
    public ResponseEntity<ApiResult> sizeLimitExceededExceptionHandler(SizeLimitExceededException e) {
        String message = e.getMessage();
        log.error("SizeLimitExceededException异常：", e);
        return ApiResultEnum.sizeLimitExceededException(message);
    }

    /**
     * Required request body is missing
     * 缺少所需的请求正文
     *
     * @param e
     * @return
     * @ExceptionHandler
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public ResponseEntity<ApiResult> httpMessageNotReadableExceptionHandler(HttpMessageNotReadableException e) {
        String message = e.getMessage();
        log.error("HttpMessageNotReadableException异常：", e);
        return ApiResultEnum.httpMessageNotReadableException(message);
    }
}
